package be.dch.objectprops.collector;

import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.google.inject.Singleton;

@SuppressWarnings({ "rawtypes", "unchecked" })
@Singleton
public class OrderedProperties extends Properties implements Collector {

    private static final long serialVersionUID = -2626364832825841320L;
    private final Map<String, String> entries;

    public OrderedProperties() {
	this.entries = new LinkedHashMap<String, String>();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#getProperty(java.lang.String)
     */
    @Override
    public String getProperty(final String key) {
	return entries.get(key);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#keys()
     */
    @Override
    public Enumeration keys() {
	final Set<String> keySet = this.entries.keySet();
	return Collections.enumeration(keySet);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#elements()
     */
    @Override
    public Enumeration elements() {
	return Collections.enumeration(this.entries.values());
    }


    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#putAll(java.util.Map)
     */
    @Override
    public void putAll(final Map map) {
	this.entries.putAll(map);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#size()
     */
    @Override
    public int size() {
	return this.entries.size();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#isEmpty()
     */
    @Override
    public boolean isEmpty() {
	return this.entries.isEmpty();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#containsKey(java.lang.Object)
     */
    @Override
    public boolean containsKey(final Object key) {
	return this.entries.containsKey(key);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#containsValue(java.lang.Object)
     */
    @Override
    public boolean containsValue(final Object value) {
	return this.entries.containsValue(value);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#get(java.lang.Object)
     */
    @Override
    public Object get(final Object key) {
	return this.entries.get(key);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#put(java.lang.Object, java.lang.Object)
     */
    @Override
    public Object put(final Object key, final Object value) {
	if (!(key instanceof String) || !(value instanceof String)){
	    return null;
	}
	return this.entries.put((String) key, (String) value);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#remove(java.lang.Object)
     */
    @Override
    public Object remove(final Object key) {
	return this.entries.remove(key);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#clear()
     */
    @Override
    public void clear() {
	this.entries.clear();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#keySet()
     */
    @Override
    public Set keySet() {
	return this.entries.keySet();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#values()
     */
    @Override
    public Collection values() {
	return this.entries.values();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#entrySet()
     */
    @Override
    public Set entrySet() {
	return this.entries.entrySet();
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object o) {
	return this.entries.equals(o);
    }

    /*
     * (non-Javadoc)
     * 
     * @see be.dch.objectprops.Collect#hashCode()
     */
    @Override
    public int hashCode() {
	return this.entries.hashCode();
    }

    public boolean startWithKey(final String key) {
	final Set<String> inEntrySet = this.entries.keySet();

	for (final String entry : inEntrySet) {
	    if (entry.startsWith(key)) {
		return true;
	    }
	}
	return false;
    }

}